<template>
  <div class="image-viewer-app">
    <div class="toolbar">
      <el-upload
        action="#"
        :auto-upload="false"
        :show-file-list="false"
        :on-change="handleFileChange"
        accept="image/*"
      >
        <el-button type="primary">
          <el-icon><Upload /></el-icon> 打开图片
        </el-button>
      </el-upload>
      
      <div class="tool-divider"></div>
      
      <el-button-group>
        <el-button 
          :disabled="!currentImage"
          @click="zoomIn"
        >
          <el-icon><ZoomIn /></el-icon>
        </el-button>
        <el-button 
          :disabled="!currentImage"
          @click="zoomOut"
        >
          <el-icon><ZoomOut /></el-icon>
        </el-button>
        <el-button 
          :disabled="!currentImage"
          @click="resetZoom"
        >
          <el-icon><Refresh /></el-icon>
        </el-button>
      </el-button-group>
      
      <div class="tool-divider"></div>
      
      <el-button-group>
        <el-button 
          :disabled="!currentImage"
          @click="rotateLeft"
        >
          <el-icon><RefreshLeft /></el-icon>
        </el-button>
        <el-button 
          :disabled="!currentImage"
          @click="rotateRight"
        >
          <el-icon><RefreshRight /></el-icon>
        </el-button>
      </el-button-group>
      
      <div class="tool-divider"></div>
      
      <el-button 
        :disabled="!currentImage"
        @click="downloadImage"
      >
        <el-icon><Download /></el-icon> 下载
      </el-button>
    </div>
    
    <div class="viewer-container" @wheel.prevent="handleWheel">
      <div v-if="!currentImage" class="empty-state">
        <el-empty description="请打开一张图片">
          <el-upload
            action="#"
            :auto-upload="false"
            :show-file-list="false"
            :on-change="handleFileChange"
            accept="image/*"
          >
            <el-button type="primary">打开图片</el-button>
          </el-upload>
        </el-empty>
      </div>
      
      <div v-else class="image-container">
        <img
          :src="currentImage"
          alt="预览图片"
          :style="{
            transform: `scale(${zoomLevel}) rotate(${rotationDegree}deg)`,
            cursor: isDragging ? 'grabbing' : 'grab'
          }"
          @mousedown.prevent="startDrag"
          @mousemove.prevent="onDrag"
          @mouseup.prevent="stopDrag"
          @mouseleave="stopDrag"
          ref="imageRef"
        />
      </div>
    </div>
    
    <div class="status-bar">
      <div v-if="currentImageInfo">
        <span>{{ currentImageInfo.name }}</span>
        <span class="status-separator">|</span>
        <span>{{ currentImageInfo.dimensions }}</span>
        <span class="status-separator">|</span>
        <span>{{ currentImageInfo.size }}</span>
      </div>
      <div v-else>无图片信息</div>
      
      <div>
        <span>缩放: {{ Math.round(zoomLevel * 100) }}%</span>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onUnmounted } from 'vue'
import { Upload, Download, ZoomIn, ZoomOut, Refresh, RefreshLeft, RefreshRight } from '@element-plus/icons-vue'

// 当前图片
const currentImage = ref<string | null>(null)
const currentImageInfo = ref<{
  name: string;
  dimensions: string;
  size: string;
} | null>(null)

// 图片引用
const imageRef = ref<HTMLImageElement | null>(null)

// 缩放级别
const zoomLevel = ref(1)
const zoomStep = 0.1
const minZoom = 0.1
const maxZoom = 5

// 旋转角度
const rotationDegree = ref(0)

// 拖动状态
const isDragging = ref(false)
const dragStart = reactive({ x: 0, y: 0 })
const currentPosition = reactive({ x: 0, y: 0 })

// 处理文件选择
const handleFileChange = (file: any) => {
  if (!file) return
  
  const reader = new FileReader()
  reader.onload = (e) => {
    if (e.target?.result) {
      currentImage.value = e.target.result as string
      
      // 加载图片信息
      const img = new Image()
      img.src = currentImage.value
      img.onload = () => {
        currentImageInfo.value = {
          name: file.name,
          dimensions: `${img.naturalWidth} × ${img.naturalHeight}`,
          size: formatFileSize(file.size)
        }
      }
      
      // 重置缩放和旋转
      resetZoom()
      rotationDegree.value = 0
      
      // 重置拖动位置
      currentPosition.x = 0
      currentPosition.y = 0
    }
  }
  reader.readAsDataURL(file.raw)
}

// 格式化文件大小
const formatFileSize = (bytes: number) => {
  if (bytes === 0) return '0 B'
  
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  
  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`
}

// 缩放功能
const zoomIn = () => {
  if (zoomLevel.value < maxZoom) {
    zoomLevel.value += zoomStep
    zoomLevel.value = Math.min(zoomLevel.value, maxZoom)
  }
}

const zoomOut = () => {
  if (zoomLevel.value > minZoom) {
    zoomLevel.value -= zoomStep
    zoomLevel.value = Math.max(zoomLevel.value, minZoom)
  }
}

const resetZoom = () => {
  zoomLevel.value = 1
}

// 处理鼠标滚轮缩放
const handleWheel = (e: WheelEvent) => {
  if (!currentImage.value) return
  
  if (e.deltaY < 0) {
    zoomIn()
  } else {
    zoomOut()
  }
}

// 旋转功能
const rotateLeft = () => {
  rotationDegree.value -= 90
}

const rotateRight = () => {
  rotationDegree.value += 90
}

// 拖动功能
const startDrag = (e: MouseEvent) => {
  if (!currentImage.value) return
  
  isDragging.value = true
  dragStart.x = e.clientX - currentPosition.x
  dragStart.y = e.clientY - currentPosition.y
}

const onDrag = (e: MouseEvent) => {
  if (!isDragging.value || !currentImage.value) return
  
  currentPosition.x = e.clientX - dragStart.x
  currentPosition.y = e.clientY - dragStart.y
  
  if (imageRef.value) {
    imageRef.value.style.marginLeft = `${currentPosition.x}px`
    imageRef.value.style.marginTop = `${currentPosition.y}px`
  }
}

const stopDrag = () => {
  isDragging.value = false
}

// 下载图片
const downloadImage = () => {
  if (!currentImage.value || !currentImageInfo.value) return
  
  const link = document.createElement('a')
  link.href = currentImage.value
  link.download = currentImageInfo.value.name
  link.click()
}

// 清理事件
onUnmounted(() => {
  if (currentImage.value) {
    URL.revokeObjectURL(currentImage.value)
  }
})
</script>

<style scoped>
.image-viewer-app {
  height: 100%;
  display: flex;
  flex-direction: column;
  background-color: #282c34;
  color: white;
}

.toolbar {
  padding: 10px;
  display: flex;
  align-items: center;
  gap: 10px;
  background-color: #1e1e1e;
  border-bottom: 1px solid #333;
}

.tool-divider {
  width: 1px;
  height: 24px;
  background-color: #444;
  margin: 0 5px;
}

.viewer-container {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
  background-color: #1e1e1e;
}

.empty-state {
  padding: 20px;
  text-align: center;
}

.image-container {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.image-container img {
  max-width: 100%;
  max-height: 100%;
  transition: transform 0.2s ease;
  user-select: none;
}

.status-bar {
  padding: 8px 12px;
  background-color: #1e1e1e;
  border-top: 1px solid #333;
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: #aaa;
}

.status-separator {
  margin: 0 8px;
  color: #666;
}

:deep(.el-empty__description) {
  color: white;
}
</style> 